"Filed out from Dolphin Smalltalk 7"!

Object subclass: #RoundedRateCombiningCalculator
	instanceVariableNames: 'shifts roundPer combinePer'
	classVariableNames: ''
	poolDictionaries: ''
	classInstanceVariableNames: ''!
RoundedRateCombiningCalculator guid: (GUID fromString: '{3F9527B5-A15D-4F4A-A0F6-DEA954A0F3B0}')!
RoundedRateCombiningCalculator comment: ''!
!RoundedRateCombiningCalculator categoriesForClass!Unclassified! !
!RoundedRateCombiningCalculator methodsFor!

combinedAndRoundedShiftGroups
	^self roundOrCombine: self combinePer
		shifts: (self roundOrCombine: self roundPer shifts: self shifts).!

combinedAndRoundedShiftGroupsWithFudgingNeeded
	| combinedAmounts |
	combinedAmounts := OrderedCollection new.
	(self roundPer partitionShifts: (self roundOrCombine: self combinePer shifts: self shifts)) 
		with: (self roundOrCombine: self roundPer shifts: self shifts)
		do: 
			[:combiningShiftGroupsBlob :roundedGroup | 
			self fudgeShiftsIn: combiningShiftGroupsBlob toMatchTotalOf: roundedGroup.
			combinedAmounts addAll: (combiningShiftGroupsBlob select: [:each | each computedUnits > 0])].
	^combinedAmounts.!

combinePer
	^combinePer!

finalAmounts
	^self finalResults collect: #computedAmount.!

finalResults
	^(combinePer isNotSmallerThan: roundPer) 
		ifTrue: [self combinedAndRoundedShiftGroups]
		ifFalse: [self combinedAndRoundedShiftGroupsWithFudgingNeeded].!

finalUnits
	^self finalResults collect: #computedUnits.!

fudgeShiftsIn: combiningShiftGroupsBlob toMatchTotalOf: roundedGroup 
	| fudgingNeeded direction |
	fudgingNeeded := roundedGroup computedUnits - (combiningShiftGroupsBlob sum: #computedUnits).
	direction := fudgingNeeded sign.
	[fudgingNeeded isZero] whileFalse: 
			[(combiningShiftGroupsBlob detectMin: [:each | each computedUnits * direction]) fudgeBy: direction.
			fudgingNeeded := fudgingNeeded - direction].!

initializeForShifts: aShiftCollection roundingPer: rMode combiningPer: cMode 
	shifts := aShiftCollection asOrderedCollection.
	roundPer := rMode.
	combinePer := cMode.
	self shifts anyElement 
		ifNotNil: [:a | a billRate rateType requiresRoundingMode ifFalse: [roundPer := ReportCombiningType shift]].!

roundOrCombine: rcType shifts: aShiftCollection 
	^(rcType partitionShifts: aShiftCollection) 
		collect: [:shiftBlob | AccountingShiftGroupModel newForShifts: shiftBlob].!

roundPer
	^roundPer!

shifts
	^shifts.! !
!RoundedRateCombiningCalculator categoriesFor: #combinedAndRoundedShiftGroups!private! !
!RoundedRateCombiningCalculator categoriesFor: #combinedAndRoundedShiftGroupsWithFudgingNeeded!private! !
!RoundedRateCombiningCalculator categoriesFor: #combinePer!accessing!private! !
!RoundedRateCombiningCalculator categoriesFor: #finalAmounts!public! !
!RoundedRateCombiningCalculator categoriesFor: #finalResults!public! !
!RoundedRateCombiningCalculator categoriesFor: #finalUnits!public! !
!RoundedRateCombiningCalculator categoriesFor: #fudgeShiftsIn:toMatchTotalOf:!private! !
!RoundedRateCombiningCalculator categoriesFor: #initializeForShifts:roundingPer:combiningPer:!public! !
!RoundedRateCombiningCalculator categoriesFor: #roundOrCombine:shifts:!private! !
!RoundedRateCombiningCalculator categoriesFor: #roundPer!accessing!private! !
!RoundedRateCombiningCalculator categoriesFor: #shifts!accessing!private! !

!RoundedRateCombiningCalculator class methodsFor!

newForShifts: aShiftCollection roundingPer: rMode combiningPer: cMode 
	^self new 
		initializeForShifts: aShiftCollection
		roundingPer: rMode
		combiningPer: cMode.! !
!RoundedRateCombiningCalculator class categoriesFor: #newForShifts:roundingPer:combiningPer:!public! !

